package org.koyad.portal.context;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionContext;

import org.koyad.portal.constants.FrameworkConstants;
import org.koyad.portal.exceptions.ErrorCodes;
import org.koyad.portal.exceptions.FrameworkException;
import org.koyad.portal.tags.ViewRoot;

public class PistonSession implements HttpSession {

	private HttpSession _session = null;
	private String _requestTileId = null;
	private List<String> _tileIds = new ArrayList<String>();
	
	public PistonSession(HttpSession session, String requestTileId) {
		_session = session;
		_requestTileId = requestTileId;
	}
	
	private Map<String, Object> getTileMap() {
		Map<String, Object> map = (Map<String, Object>)_session.getAttribute(getCurrentTileId());
		if(null == map) {
			map = new HashMap<String, Object>();
			_session.setAttribute(getCurrentTileId(), map);
			_tileIds.add(getCurrentTileId());
		}
		return map;
	}
	
	public ViewRoot getViewRoot() {
		return (ViewRoot)_session.getAttribute(FrameworkConstants.PISTON_VIEW_ROOT);
	}
	
	private String getCurrentTileId() {
		if(null != getViewRoot()) {
			return getViewRoot().getCurrentTileId();
		}
		return null;
	}
	
	@Override
	public Object getAttribute(String name) {
		Object value = null;
		if (null == _requestTileId && null == getCurrentTileId()) {
			value =  _session.getAttribute(name);
		} else {
			value = getTileMap().get(name);
		}
		return value;
	}

	@Override
	public Enumeration<String> getAttributeNames() {
		Enumeration<String> value = Collections.enumeration(new HashSet<String>());
		if (null == _requestTileId && null == getCurrentTileId()) {
			value = _session.getAttributeNames();
		} else {
			value = Collections.enumeration(getTileMap().keySet());
		}
		return value;
	}

	@Override
	public long getCreationTime() {
		return _session.getCreationTime();
	}

	@Override
	public String getId() {
		return _session.getId();
	}

	@Override
	public long getLastAccessedTime() {
		return _session.getLastAccessedTime();
	}

	@Override
	public int getMaxInactiveInterval() {
		return _session.getMaxInactiveInterval();
	}

	@Override
	public ServletContext getServletContext() {
		return _session.getServletContext();
	}

	@Override
	public HttpSessionContext getSessionContext() {
		return _session.getSessionContext();
	}

	@Override
	public Object getValue(String arg0) {
		return _session.getValue(arg0);
	}

	@Override
	public String[] getValueNames() {
		return _session.getValueNames();
	}

	@Override
	public void invalidate() {
		if(null == getCurrentTileId()) {
			_session.invalidate();
		} else {
			throw new FrameworkException(ErrorCodes.FWKPS001);
		}

	}

	@Override
	public boolean isNew() {
		return _session.isNew();
	}

	@Override
	public void putValue(String arg0, Object arg1) {
		_session.putValue(arg0, arg1);
	}

	@Override
	public void removeAttribute(String name) {
		if (null == _requestTileId && null == getCurrentTileId()) {
			if(!_tileIds.contains(name)) {
				_session.removeAttribute(name);
			} else {
				throw new FrameworkException(ErrorCodes.FWKPR002);
			}
		} else {
			getTileMap().remove(name);
		}
	}

	@Override
	public void removeValue(String arg0) {
		_session.removeValue(arg0);
	}

	@Override
	public void setAttribute(String name, Object value) {
		if (null == _requestTileId && null == getCurrentTileId()) {
			if(!_tileIds.contains(name)) {
				_session.setAttribute(name, value);
			} else {
				throw new FrameworkException(ErrorCodes.FWKPR001);
			}
		} else {
			getTileMap().put(name, value);
		}
	}

	@Override
	public void setMaxInactiveInterval(int arg0) {
		_session.getMaxInactiveInterval();
	}

}
